#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qmessagebox.h"
#include "qcheckbox.h"
#include "qtablewidget.h"

#include "strings.h"
#include "frmsetting.h"
#include "frmrcd_lsgcc.h"
#include "ultils.h"

using namespace Qt;
using namespace RFIDLIB;
using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

void MainWindow::paintEvent(QPaintEvent *e)
{
    if(!loaded)//首次 加载完成
    {
        loaded=true;

        initControlData();
        enableControls(false,ui->cmb_commtype->currentIndex());
        RDType=QString("%1").arg("");
        ui->myTabs->setCurrentIndex(0);
        m_tags_hf.clear();
        m_tags_uhf.clear();

        for(int i=0;i<UHF_TAG_MAX_WORD_NUMBER;i++)
        {
            ui->cmb_access_word_start->addItem(QString("%1").arg(i),i);
            ui->cmb_access_word_count->addItem(QString("%1").arg(i+1),i+1);
        }
        ui->cmb_access_word_start->setCurrentIndex(2);
        ui->cmb_access_word_start->setEditable(true);
        ui->cmb_access_word_count->setEditable(true);
        pltSuccess.setColor(QPalette::WindowText,Qt::black);
        pltFail.setColor(QPalette::WindowText,Qt::red);


        create_reader();

        create_scan_mode_view();

    }
}
MainWindow::~MainWindow()
{
    on_btn_close_clicked();
    if(m_rdr!=NULL)
        delete m_rdr;
    if(invenParams != NULL)
    {
        delete invenParams;
        invenParams = NULL;
    }
    delete ui;
}

void MainWindow::set_info(QString str,bool success)
{
    m_lbl_info->setText(str);
    if(success)
        m_lbl_info->setPalette(pltSuccess);
    else
        m_lbl_info->setPalette(pltFail);
}
void MainWindow::update_access_position()
{
    QSize szAcc = ui->myTabs->currentWidget()->size();
    QSize szGrp = m_fra_access->size();
    m_fra_access->move((szAcc.width()-szGrp.width())/2,(szAcc.height()-szGrp.height())/2);
}
void MainWindow::create_inventory_view()
{
    ui->tbw_inventory_tags->clear();
    QStringList strList;
    BYTE* szRate;
    int columns=6;
    if(Device_Type == DEVICE_TYPE_HF)
    {
        strList<<tr("AntID")<<tr("Air Protocol")<<tr("Tag Type")<<tr("UID")<<tr("RSSI")<<tr("Read Count");
        columns=strList.length();
        szRate=new BYTE[columns]{1,1,1,2,1,1};
    }
    else if(Device_Type == DEVICE_TYPE_UHF)
    {
        strList<<tr("AntID")<<tr("EPC")<<tr("Tag Data")<<tr("Timestamp")<<tr("Freq")<<tr("RSSI")<<tr("ReadCnt")<<tr("Write");
        columns=strList.length();
        szRate=new BYTE[columns]{3,10,6,4,3,3,3,3};
    }

    ui->tbw_inventory_tags->setColumnCount(columns);
    ui->tbw_inventory_tags->setHorizontalHeaderLabels(strList);
    int wid=ui->tbw_inventory_tags->size().width()-38;
    int szSum=0;
    for(int i=0;i<columns;i++)
    {
        szSum +=szRate[i];
    }
    for(int i=0;i<columns;i++)
    {
        ui->tbw_inventory_tags->setColumnWidth(i,szRate[i]*wid/szSum);
    }
    delete[] szRate;

    ui->tbw_inventory_tags->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tbw_inventory_tags->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tbw_inventory_tags->setEditTriggers(QAbstractItemView::NoEditTriggers);

    ui->btn_inventory_setting->setVisible((Device_Type == DEVICE_TYPE_UHF) ? true:false);
}

void MainWindow::create_scan_mode_view()
{
    ui->tbw_scan_mode_tags->clear();
    QStringList strList;
    BYTE* szRate;
    int columns=2;
    strList<<tr("Tag Data")<<tr("Read Count");
    columns=strList.length();
    szRate=new BYTE[columns]{4,1};

    ui->tbw_scan_mode_tags->setColumnCount(columns);
    ui->tbw_scan_mode_tags->setHorizontalHeaderLabels(strList);
    int wid=ui->tbw_scan_mode_tags->size().width()-38;
    int szSum=0;
    for(int i=0;i<columns;i++)
    {
        szSum +=szRate[i];
    }
    for(int i=0;i<columns;i++)
    {
        ui->tbw_scan_mode_tags->setColumnWidth(i,szRate[i]*wid/szSum);
    }
    delete[] szRate;

    ui->tbw_scan_mode_tags->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tbw_scan_mode_tags->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tbw_scan_mode_tags->setEditTriggers(QAbstractItemView::NoEditTriggers);

    ui->tbw_scan_mode_tags->setVisible(true);
}
void MainWindow::update_net_port()
{
    if(RDType.contains(QString("PAN")))
        ui->cmb_tcp_port->setCurrentIndex(0);
    else if(RDType.contains(QString("LSG")))
        ui->cmb_tcp_port->setCurrentIndex(1);
    else if(RDType.contains(QString("RL")))
        ui->cmb_tcp_port->setCurrentIndex(2);
    else
        ui->cmb_tcp_port->setCurrentIndex(3);
}

void MainWindow::refresh_uhf_pwds()
{
    if( invenParams == NULL)
        return;
    char tmp[9]={0};
    Numeric2HexStr(invenParams->m_accessPwd,tmp,4,false);
    ui->txt_access_pwd->setText(QString(tmp));
    memset(tmp,'\0',9);
    Numeric2HexStr(invenParams->m_killPwd,tmp,4,false);
    ui->txt_kill_pwd->setText(QString(tmp));
    ui->txt_access_pwd->setEnabled(false);
    ui->txt_kill_pwd->setEnabled(false);
}

void MainWindow::create_reader()
{
    //获取读卡器类型
    RDType= ui->cmb_rdtype->currentText();
    bool b_chg=false;
    int Last_Dev_Type = Device_Type;
    if(RDType==QString("LSGControlCenter"))
    {
        if(Device_Type != DEVICE_TYPE_LSGCC)
        {
            Device_Type = DEVICE_TYPE_LSGCC;
            m_lbl_info = ui->lbl_info_lsgcc;
            m_fra_access = ui->fra_access_lsgcc;
            b_chg=true;
            ui->myTabs->clear();
            ui->myTabs->addTab(ui->tab_cmd_rcd_lsgcc,QString("Command && Record"));
        }
    }
    else if(RDType.contains("U"))
    {
        if(Device_Type != DEVICE_TYPE_UHF)
        {
            Device_Type = DEVICE_TYPE_UHF;
            m_cmb_access = ui->cmb_access_epcs;
            m_lbl_info = ui->lbl_info_mem;
            m_fra_access = ui->fra_access_uhf;
            b_chg=true;
            ui->myTabs->clear();
            ui->myTabs->addTab(ui->tab_inventory,QString("Inventory"));
            ui->myTabs->addTab(ui->tab_access_uhf,QString("Access"));
        }
        if(RDType.contains("PAN"))
        {
             if(ui->myTabs->count()<=2)
             {
                ui->myTabs->addTab(ui->tab_scan_mode,QString("Scan Mode"));
                setWidgetEnable(ui->btn_scan_mode_stop,false);
             }
        }
        else
        {
            if(ui->myTabs->count()>2)
               ui->myTabs->removeTab(2);
        }
    }
    else if(!RDType.contains("U"))//HF
    {
        if(Device_Type != DEVICE_TYPE_HF)
        {
            Device_Type = DEVICE_TYPE_HF;
            m_cmb_access = ui->cmb_access_tags;
            m_lbl_info = ui->lbl_info;
            m_fra_access = ui->fra_access_hf;
            b_chg=true;
            ui->myTabs->clear();
            ui->myTabs->addTab(ui->tab_inventory,QString("Inventory"));
            ui->myTabs->addTab(ui->tab_access_hf,QString("Access"));
        }
        if(RDType.contains("PAN"))
        {
            if(ui->myTabs->count()<=2)
            {
               ui->myTabs->addTab(ui->tab_scan_mode,QString("Scan Mode"));
               setWidgetEnable(ui->btn_scan_mode_stop,false);
            }
        }
        else
        {
            if(ui->myTabs->count()>2)
               ui->myTabs->removeTab(2);
        }
    }

    //类型变化
    if(b_chg)
    {
        if(m_rdr != NULL)
        {
            disconnect(m_rdr,SIGNAL(sgnl_scan_mode_data(int, vector<CScan_Record>, int, int)),this,SLOT(slot_scan_mode_data(int, vector<CScan_Record>, int, int)));
            disconnect(m_rdr,SIGNAL(sgnl_scan_mode_end_loop(int)),this,SLOT(slot_scan_mode_end_loop(int)));
        }
        if(Device_Type == DEVICE_TYPE_LSGCC){
            if(m_rdr != NULL)
            {
                if(Last_Dev_Type == DEVICE_TYPE_HF)
                {
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_data_hf(int, vector<CTag_HF>, int, int)),this,SLOT(slot_inventory_data_hf(int, vector<CTag_HF>, int, int)));
                    disconnect(m_rdr,SIGNAL(sgnl_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));
                }
                else if(Last_Dev_Type == DEVICE_TYPE_UHF)
                {
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_data_uhf(int, vector<CTag_UHF>, int, int)),this,SLOT(slot_inventory_data_uhf(int, vector<CTag_UHF>, int, int)));
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));
                }
                delete m_rdr;
            }

            m_rdr = new CRFID_LSG_CC();
            init_lsgcc_sgl_door();
            //register unstandard data type

        }
        else if(Device_Type == DEVICE_TYPE_UHF)
        {
            if(m_rdr != NULL)
            {
                if(Last_Dev_Type == DEVICE_TYPE_HF)
                {
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_data_hf(int, vector<CTag_HF>, int, int)),this,SLOT(slot_inventory_data_hf(int, vector<CTag_HF>, int, int)));
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));
                }
                delete m_rdr;
            }

            if(invenParams == NULL)
            {
                invenParams = new InvenParams(this->UHF_TAG_MAX_WORD_NUMBER*2);
                refresh_uhf_pwds();
            }
            m_rdr = new CAEDevice_UHF(invenParams);
            //register unstandard data type
            qRegisterMetaType<vector<CTag_UHF>>("vector<CTag_UHF>");

            connect(m_rdr,SIGNAL(sgnl_inventory_data_uhf(int, vector<CTag_UHF>, int, int)),this,SLOT(slot_inventory_data_uhf(int, vector<CTag_UHF>, int, int)));
            connect(m_rdr,SIGNAL(sgnl_inventory_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));

        }
        else if(Device_Type == DEVICE_TYPE_HF)
        {
            if(m_rdr != NULL)
            {
                if(Last_Dev_Type == DEVICE_TYPE_UHF)
                {
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_data_uhf(int, vector<CTag_UHF>, int, int)),this,SLOT(slot_inventory_data_uhf(int, vector<CTag_UHF>, int, int)));
                    disconnect(m_rdr,SIGNAL(sgnl_inventory_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));
                }
                delete m_rdr;
            }
            m_rdr = new CAEDevice_HF();
            //register unstandard data type
            qRegisterMetaType<vector<CTag_HF>>("vector<CTag_HF>");
            connect(m_rdr,SIGNAL(sgnl_inventory_data_hf(int, vector<CTag_HF>, int, int)),this,SLOT(slot_inventory_data_hf(int, vector<CTag_HF>, int, int)));
            connect(m_rdr,SIGNAL(sgnl_inventory_end_loop(int)),this,SLOT(slot_inventory_end_loop(int)));
        }

        //register unstandard data type
        qRegisterMetaType<vector<CScan_Record>>("vector<CScan_Record>");
        connect(m_rdr,SIGNAL(sgnl_scan_mode_data(int, vector<CScan_Record>, int, int)),this,SLOT(slot_scan_mode_data(int, vector<CScan_Record>, int, int)));
        connect(m_rdr,SIGNAL(sgnl_scan_mode_end_loop(int)),this,SLOT(slot_scan_mode_end_loop(int)));

        if(Device_Type <= DEVICE_TYPE_UHF)
            create_inventory_view();
    }

    if(ui->cmb_commtype->currentText() == QString("NET"))
        update_net_port();//更新网络端口

    update_access_position();
}

void MainWindow::bind_antennas()
{
    ui->lw_ants->clear();
    DWORD ant_cnt=m_rdr->get_antenna_count();
    QString str;
    for (int i = 1; i <= ant_cnt; ++i) {
        str.sprintf("#%d",i);
        QListWidgetItem* chk=new QListWidgetItem();
        chk->setData(DisplayRole,"text");
        chk->setData(CheckStateRole, Checked);
        chk->setData(UserRole, i);//set user data(start from 1)
        chk->setText(str);
        if(i==1)
            chk->setCheckState(CheckState::Checked);
        else
            chk->setCheckState(CheckState::Unchecked);
        ui->lw_ants->addItem(chk);
    }
}
void MainWindow::setWidgetEnable(QWidget *m_wid,bool enable)
{
    m_wid->setEnabled(enable);
    qApp->processEvents();
    m_wid->repaint();
}

void MainWindow::enableCommGroup(bool opened,int comm_index)
{
    if(!opened)
    {
        if(comm_index==0)//com
        {
            setWidgetEnable(ui->grpCOM,!opened);
            setWidgetEnable(ui->grpUSB,opened);
            setWidgetEnable(ui->grpTCP,opened);

        }
        else if(comm_index==1)//usb
        {
            setWidgetEnable(ui->grpCOM,opened);
            setWidgetEnable(ui->grpUSB,!opened);
            setWidgetEnable(ui->grpTCP,opened);

        }
        else if(comm_index==2)//tcp
        {
            setWidgetEnable(ui->grpCOM,opened);
            setWidgetEnable(ui->grpUSB,opened);
            setWidgetEnable(ui->grpTCP,!opened);
            int cnt=NET_Enum();
            int iret=0;
            DWORD len=255;
            ui->cmb_local_tcp_ip->clear();
            if(cnt>0)
            {
                LPTSTR str=new TCHAR[len]{'\0'};
                for (int i = 0; i < cnt; ++i) {
                    memset(str,'\0',255);
                    iret=NET_GetEnumItem(i,IP_ENUM_INF_TYPE_IP,str,&len);
                    if(iret==NO_ERR)
                    {
                        QString strs = QString("%1").arg(str);
                        ui->cmb_local_tcp_ip->addItem(strs);
                    }
                }
                delete[] str;
            }
            update_net_port();
        }
    }
    else {
        setWidgetEnable(ui->grpCOM,!opened);
        setWidgetEnable(ui->grpUSB,!opened);
        setWidgetEnable(ui->grpTCP,!opened);
    }

}

void MainWindow::enableControls(bool opened,int comm_index)
{
    setWidgetEnable(ui->btn_close,opened);
    setWidgetEnable(ui->btn_getinfo,opened);
    setWidgetEnable(ui->btn_inventory_stop,opened);
    setWidgetEnable(ui->myTabs,opened);

    setWidgetEnable(ui->cmb_rdtype,!opened);
    setWidgetEnable(ui->cmb_commtype,!opened);
    setWidgetEnable(ui->btn_open,!opened);
    setWidgetEnable(ui->btn_inventory_stop,!opened);

    enableCommGroup(opened, comm_index);

}

//communication type changed
void MainWindow::on_cmb_commtype_currentIndexChanged(int index)
{
    enableCommGroup(false,index);
}

void MainWindow::initControlData()
{
    ui->cmb_com_baud->setItemData(0,9600);
    ui->cmb_com_baud->setItemData(1,38400);
    ui->cmb_com_baud->setItemData(2,57600);
    ui->cmb_com_baud->setItemData(3,115200);

    ui->cmb_tcp_port->setItemData(0,4800);
    ui->cmb_tcp_port->setItemData(1,6012);
    ui->cmb_tcp_port->setItemData(2,9900);
    ui->cmb_tcp_port->setItemData(3,9909);
    setTagBlockNums(28);//set tag default 28 blocks



    ui->cmb_com_name->setCurrentIndex(6);//COM ttyUSB0
    ui->cmb_com_baud->setCurrentIndex(1);//8400
    //测试使用默认值
    int start_rdr_idx=0;
    int start_com_idx=0;
    ui->txt_tcp_ip->setText(QString("192.168.1.227"));
    ui->cmb_rdtype->setCurrentIndex(start_rdr_idx);//3:UM200 4:LSGControlCenter
    ui->cmb_commtype->setCurrentIndex(start_com_idx);//0:COM 1:USB 2:NET
    on_cmb_rdtype_currentIndexChanged(start_rdr_idx);
}

void MainWindow::getConnectString(char *&connStr)
{
    RDType=ui->cmb_rdtype->currentText();
    QString CommType=ui->cmb_commtype->currentText();
    int CommIndex=ui->cmb_commtype->currentIndex();
    if(CommIndex==0)//COM
    {
        QString COMName=ui->cmb_com_name->currentText();
        int BaudRate=ui->cmb_com_baud->currentData().toInt();
        QString Frame=ui->cmb_com_frame->currentText();

        sprintf(connStr,"RDType=%s;CommType=%s;COMName=%s;BaudRate=%d;Frame=%s;BusAddr=255",
                RDType.toStdString().c_str(),
                CommType.toStdString().c_str(),
                COMName.toStdString().c_str(),
                BaudRate,
                Frame.toStdString().c_str());
    }
    else if(CommIndex==1)//USB
    {
        int AddrMode=ui->cmb_usb_opentype->currentIndex();
        QString SerNum="\0";
        if(AddrMode > 0)
        {
            SerNum=ui->cmb_usb_sn_path->currentText();
            if(SerNum.isEmpty()|| SerNum.isNull())
            {
                *connStr=NULL;
                QMessageBox::warning(this,"Connect String","No USB Device Selected!",QMessageBox::Ok);
                return;
            }
        }
        sprintf(connStr,"RDType=%s;CommType=%s;AddrMode=%d;SerNum=%s",
                RDType.toStdString().c_str(),
                CommType.toStdString().c_str(),
                AddrMode,
                SerNum.toStdString().c_str());
    }
    else if(CommIndex==2)//TCP
    {
        QString RemoteIP=ui->txt_tcp_ip->text().trimmed();
        int RemotePort=ui->cmb_tcp_port->currentData().toInt();
        QString LocalIP=ui->cmb_local_tcp_ip->currentText().trimmed();
        sprintf(connStr,"RDType=%s;CommType=%s;RemoteIP=%s;RemotePort=%d;LocalIP=%s",
                RDType.toStdString().c_str(),
                CommType.toStdString().c_str(),
                RemoteIP.toStdString().c_str(),
                RemotePort,LocalIP.toStdString().c_str());
    }
    printf("connStr :%s\n",connStr);
}

void MainWindow::get_selected_antennas(BYTE ants[],int &len)
{
    DWORD ant_cnt=ui->lw_ants->count();
    if(len < ant_cnt)
    {
        len=0;
        return;
    }
    len=0;
    for (int i = 0; i < ant_cnt; ++i) {
        if(ui->lw_ants->item(i)->checkState()==CheckState::Checked)
        {
            ants[len]=ui->lw_ants->item(i)->data(UserRole).toInt();//get userrole data
            len++;
        }
    }
}

//Open device
void MainWindow::on_btn_open_clicked()
{
    setWidgetEnable(ui->btn_open,false);
    if(m_rdr->m_opened)
    {
        setWidgetEnable(ui->btn_open,false);
        return;
    }
    char connStr[255]={'\0'};
    char *pConn=connStr;
    getConnectString(pConn);
    if(strcmp(pConn,"")==0)
    {
        setWidgetEnable(ui->btn_open,true);
        return;
    }
    //     QMessageBox::information(this,"Connect String",connStr,QMessageBox::Ok);
    int iret = m_rdr->Open(pConn);
    if(iret != NO_ERR)
    {
        QMessageBox::critical(this,"Open Reader",QString("Open device failed! err=%1").arg(iret),QMessageBox::Ok);
        setWidgetEnable(ui->btn_open,true);
        return;
    }
    enableControls(m_rdr->m_opened,ui->cmb_commtype->currentIndex());
    bind_antennas();//绑定天线
    update_access_position();//更新Acceess位置,默认初始化时位置不居中
}

void MainWindow::on_btn_close_clicked()
{
    if(m_rdr==NULL || !m_rdr->m_opened)
        return;
    if(m_rdr->is_inventory)
    {
        on_btn_inventory_stop_clicked();
        while(m_rdr->is_inventory)
        {
            usleep(10000);//10ms
        }
    }
    int iret;
    iret=m_rdr->Close();
    if(iret != NO_ERR)
    {
        QMessageBox::critical(this,"Close Reader",QString("Close device failed! err=%1").arg(iret),QMessageBox::Ok);
    }
    enableControls(m_rdr->m_opened,ui->cmb_commtype->currentIndex());
}

void MainWindow::on_btn_getinfo_clicked()
{
    if(!m_rdr->m_opened)
        return;
    int iret;
    int len=128;
    LPTSTR info=new TCHAR[len]{'\0'};
    iret=m_rdr->GetReaderInfor(info,len);
    if(iret == NO_ERR && len>0)
    {
        QString strs = QString("%1").arg(info);
        QMessageBox::information(this,"Reader Information",strs,QMessageBox::Ok);
    }
    else {
        QMessageBox::critical(this,"Reader Information",QString("Reader Information failed! err=%1").arg(iret),QMessageBox::Ok);
    }
    //    delete[] info;
}

void MainWindow::on_cmb_usb_opentype_currentIndexChanged(int index)
{
    if(index==0)//no addr
    {
        ui->cmb_usb_sn_path->clear();
    }
    else if(index==1)//SN
    {
        ui->cmb_usb_sn_path->clear();
        int cnt=HID_Enum();
        int iret=0;
        DWORD len=13;
        if(cnt>0)
        {
            LPTSTR str=new TCHAR[len]{'\0'};
            for (int i = 0; i < cnt; ++i) {
                iret=HID_GetEnumItem(i,HID_ENUM_INF_TYPE_SERIALNUM,str,&len);
                if(iret==NO_ERR)
                {
                    QString strs = QString("%1").arg(str);
                    ui->cmb_usb_sn_path->addItem(strs);
                }
            }
            delete[] str;
        }
    }
    else if(index==2)//bus port
    {
        ui->cmb_usb_sn_path->clear();
        int cnt=HID_Enum();
        int iret=0;
        DWORD len=10;
        if(cnt>0)
        {
            LPTSTR str=new TCHAR[len]{'\0'};
            for (int i = 0; i < cnt; ++i) {
                iret=HID_GetEnumItem(i,HID_ENUM_INF_TYPE_DRIVERPATH,str,&len);
                if(iret==NO_ERR)
                {
                    QString strs = QString("%1").arg(str);
                    ui->cmb_usb_sn_path->addItem(strs);
                }
            }
            delete[] str;

        }
    }
}

//-----------------inventory tag
//start inventory
void MainWindow::on_btn_inventory_start_clicked()
{
    setWidgetEnable(ui->btn_inventory_start,false);
    setWidgetEnable(ui->btn_getinfo,false);
    if(Device_Type == DEVICE_TYPE_UHF)
        setWidgetEnable(ui->btn_inventory_setting,false);

    int ant_count=ui->lw_ants->count();
    BYTE ants[ant_count];
    memset(ants,0,sizeof(ants));
    get_selected_antennas(ants,ant_count);
    if(ant_count<=0)
    {
        setWidgetEnable(ui->btn_inventory_start,true);
        setWidgetEnable(ui->btn_getinfo,true);
        QMessageBox::warning(this,"Inventory","No Antenna Selected!",QMessageBox::Ok);
        return;
    }
    ui->tbw_inventory_tags->clearContents();
    ui->tbw_inventory_tags->setRowCount(0);
    m_tags_hf.clear();
    m_tags_uhf.clear();
    int iret=m_rdr->start_inventory(RDType.toStdString().c_str(),ants,ant_count);
    if(iret == NO_ERR)//inventory started
    {
        setWidgetEnable(ui->btn_inventory_stop,true);
    }
    else
    {
        setWidgetEnable(ui->btn_inventory_stop,false);
        setWidgetEnable(ui->btn_inventory_start,true);
        if(Device_Type == DEVICE_TYPE_UHF)
            setWidgetEnable(ui->btn_inventory_setting,true);
        setWidgetEnable(ui->btn_getinfo,true);
    }
}

//stop inventory
void MainWindow::on_btn_inventory_stop_clicked()
{
    setWidgetEnable(ui->btn_inventory_stop,false);
    m_rdr->stop_inventory();
}

void MainWindow::on_btn_inventory_clear_clicked()
{
    m_lock.Enter();
    m_tags_hf.clear();
    m_tags_uhf.clear();
    ui->tbw_inventory_tags->clearContents();
    ui->tbw_inventory_tags->setRowCount(0);
    m_cmb_access->clear();
    m_lock.Leave();
}

//inventory data return ------------BIND DATA TO VIEW
void MainWindow::slot_inventory_data_hf(int tag_count,vector<CTag_HF> tags,int use_time,int loop_count)
{
    if(tag_count<0)//inventory terminaled
    {
        return;
    }

    m_lock.Enter();
    bool exist = false;
    int sum_count = m_tags_hf.size();
    for (int i = 0; i < tag_count; ++i) {
        exist = false;
        for (int j=0; j < sum_count;++j) {
            if(tags.at(i).equal(m_tags_hf.at(j)))
            {
                m_tags_hf.at(j).m_counter ++;
                exist = true;
                break;
            }
        }
        if(!exist)
        {
            m_tags_hf.push_back(tags.at(i));
        }
    }

    sum_count = m_tags_hf.size();

    ui->tbw_inventory_tags->clearContents();
    ui->tbw_inventory_tags->setRowCount(sum_count);

    //strList<<tr("AntID")<<tr("Air Protocol")<<tr("Tag Type")<<tr("UID")<<tr("RSSI")<<tr("Read Count");
    for(int i=0;i < sum_count;i++)
    {
        ui->tbw_inventory_tags->setItem(i,0,new QTableWidgetItem(QString::number(m_tags_hf[i].m_antNo)));
        ui->tbw_inventory_tags->setItem(i,1,new QTableWidgetItem(QString::number(m_tags_hf[i].m_AIP)));
        ui->tbw_inventory_tags->setItem(i,2,new QTableWidgetItem(QString::number(m_tags_hf[i].m_type)));
        ui->tbw_inventory_tags->setItem(i,3,new QTableWidgetItem(QString(m_tags_hf[i].m_uid)));
        ui->tbw_inventory_tags->setItem(i,4,new QTableWidgetItem(QString::number(m_tags_hf[i].m_rssi)));
        ui->tbw_inventory_tags->setItem(i,5,new QTableWidgetItem(QString::number(m_tags_hf[i].m_counter)));

        ui->tbw_inventory_tags->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,3)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,4)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,5)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        //ui->tbw_inventory_tags;
    }


    ui->lbl_inventory->setText(QString("Tags: %1  \nTime: %2 ms\nLoop: %3").arg(sum_count).arg(use_time).arg(loop_count));
    m_lock.Leave();
}
void MainWindow::slot_inventory_data_uhf(int tag_count,vector<CTag_UHF> tags,int use_time,int loop_count)
{
    if(tag_count<0)//inventory terminaled
    {
        return;
    }

    m_lock.Enter();
    bool exist = false;
    int sum_count = m_tags_uhf.size();
    for (int i = 0; i < tag_count; ++i) {
        exist = false;
        for (int j=0; j < sum_count;++j) {
            if(tags.at(i).equal(m_tags_uhf.at(j)))
            {
                m_tags_uhf.at(j).m_counter ++;
                exist = true;
                break;
            }
        }
        if(!exist)
        {
            m_tags_uhf.push_back(tags.at(i));
        }
    }

    sum_count = m_tags_uhf.size();

    ui->tbw_inventory_tags->clearContents();
    ui->tbw_inventory_tags->setRowCount(sum_count);

    //strList<<tr("AntID")<<tr("EPC")<<tr("Tag Data")<<tr("Timestamp")<<tr("Freq")<<tr("RSSI")<<tr("ReadCnt")<<tr("Write");
    for(int i=0;i<sum_count;i++)
    {
        ui->tbw_inventory_tags->setItem(i,0,new QTableWidgetItem(QString::number(m_tags_uhf[i].m_antNo)));
        ui->tbw_inventory_tags->setItem(i,1,new QTableWidgetItem(m_tags_uhf[i].m_uid));
        ui->tbw_inventory_tags->setItem(i,2,new QTableWidgetItem(m_tags_uhf[i].m_rdata));
        ui->tbw_inventory_tags->setItem(i,3,new QTableWidgetItem(QString::number(m_tags_uhf[i].m_timestamp)));
        ui->tbw_inventory_tags->setItem(i,4,new QTableWidgetItem(QString::number(m_tags_uhf[i].m_frequency)));
        ui->tbw_inventory_tags->setItem(i,5,new QTableWidgetItem(QString::number(m_tags_uhf[i].m_rssi)));
        ui->tbw_inventory_tags->setItem(i,6,new QTableWidgetItem(QString::number(m_tags_uhf[i].m_counter)));
        ui->tbw_inventory_tags->setItem(i,7,new QTableWidgetItem(m_tags_uhf[i].m_writeOper));

        ui->tbw_inventory_tags->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,3)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,4)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,5)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,6)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_inventory_tags->item(i,7)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }

    ui->lbl_inventory->setText(QString("Tags: %1  \nTime: %2 ms\nLoop: %3").arg(sum_count).arg(use_time).arg(loop_count));
    m_lock.Leave();
}

//inventory ended
void MainWindow::slot_inventory_end_loop(int iret)
{
    setWidgetEnable(ui->btn_inventory_start,true);
    setWidgetEnable(ui->btn_getinfo,true);
    if(Device_Type == DEVICE_TYPE_UHF)
        setWidgetEnable(ui->btn_inventory_setting,true);
    bind_access_tags(cur_tag_index);
    if(iret < 0 && ui->btn_inventory_stop->isEnabled())
    {
        setWidgetEnable(ui->btn_inventory_stop,false);
        QMessageBox::critical(this,"Inventory",QString("Inventory failed! err=%1").arg(iret),QMessageBox::Ok);
        on_btn_inventory_stop_clicked();
    }
}

void MainWindow::on_cmb_rdtype_currentIndexChanged(int index)
{
    create_reader();
}

//bind inventory tags
void MainWindow::bind_access_tags(int tag_index)
{
    int cnt = Device_Type == DEVICE_TYPE_HF?m_tags_hf.size():m_tags_uhf.size();
    if(cnt>0)
    {
        m_cmb_access->clear();
        for(int i=0;i<cnt;i++)
        {
            m_cmb_access->addItem(Device_Type == DEVICE_TYPE_HF?m_tags_hf[i].m_uid:m_tags_uhf[i].m_uid);
        }
        if(tag_index<0)
            tag_index=0;
        if(tag_index >= 0 && tag_index < cnt)
            m_cmb_access->setCurrentIndex(tag_index);
    }
}

void MainWindow::on_myTabs_currentChanged(int index)
{
    if(m_rdr==NULL)
        return;
    //tab_Access

    if(m_rdr->is_inventory)
    {
        ui->myTabs->setCurrentIndex(0);
        return;
    }
    if(m_rdr->is_scan_mode)
    {
        ui->myTabs->setCurrentIndex(2);
        return;
    }
    if(index>0)
    {
        if(cur_tag_index<0 && (Device_Type == DEVICE_TYPE_HF?m_tags_hf.size()>0:m_tags_uhf.size()>0))
            cur_tag_index=0;
        if(Device_Type == DEVICE_TYPE_UHF)//刷新超高频密码 update UHF access and kill password
            refresh_uhf_pwds();

        m_cmb_access->setCurrentIndex(cur_tag_index);
    }
}

void MainWindow::on_tbw_inventory_tags_cellDoubleClicked(int row, int column)
{
    cur_tag_index=row;
    ui->myTabs->setCurrentIndex(1);

    m_cmb_access->setCurrentIndex(cur_tag_index);
}

void MainWindow::on_tbw_inventory_tags_cellClicked(int row, int column)
{
    cur_tag_index=row;
}

/*------------------------BEGIN-----------------------高频读卡器 HF READER */
void MainWindow::setTagBlockNums(int block_nums)
{
    int block_cnt=ui->cmb_access_block_start->count();
    if(block_nums==block_cnt)
        return;
    for(int i=block_cnt-1;i>=0;i--)
    {
        ui->cmb_access_block_count->removeItem(i);
        ui->cmb_access_block_start->removeItem(i);
    }

    for(int i=0;i<block_nums;i++)
    {
        ui->cmb_access_block_start->addItem(QString("%1").arg(i),i);
        ui->cmb_access_block_count->addItem(QString("%1").arg(i+1),i+1);
    }
    ui->cmb_access_block_start->setEditable(true);
    ui->cmb_access_block_count->setEditable(true);
    qApp->processEvents();
    ui->cmb_access_block_start->repaint();
    ui->cmb_access_block_count->repaint();
    qApp->processEvents();
}

void MainWindow::on_lw_ants_itemPressed(QListWidgetItem *item)
{
    if(item->checkState()==CheckState::Checked)
        item->setCheckState(CheckState::Unchecked);
    else
        item->setCheckState(CheckState::Checked);
}

void MainWindow::on_cmb_access_tags_currentIndexChanged(int index)
{
    if(index<0)
    {
        setWidgetEnable(ui->btn_access_write_block,false);
        setWidgetEnable(ui->btn_access_read_block,false);
        setWidgetEnable(ui->btn_access_write_afi,false);
        setWidgetEnable(ui->btn_access_open_eas,false);
        setWidgetEnable(ui->btn_access_close_eas,false);
        setWidgetEnable(ui->btn_access_get_status,false);
        return;
    }

    setWidgetEnable(ui->btn_access_write_block,true);
    setWidgetEnable(ui->btn_access_read_block,true);
    setWidgetEnable(ui->btn_access_write_afi,true);
    setWidgetEnable(ui->btn_access_open_eas,true);
    setWidgetEnable(ui->btn_access_close_eas,true);
    setWidgetEnable(ui->btn_access_get_status,true);
}

//-----------------access tag
int MainWindow::get_tag_status(CTag &tag,char *&pOut)
{
    BYTE dsfid;
    BYTE afi;
    DWORD block_size;
    DWORD block_num;
    BYTE ic_ref;

    int iret=m_rdr->func_AccessTag_GetInfor(tag,&dsfid,&afi,&block_size,&block_num,&ic_ref);
    if(iret!=NO_ERR)
    {
        set_info(QString("Get Status Failed err=%1").arg(iret),false);
        return iret;
    }
    setTagBlockNums(block_num);
    ui->txt_access_afi->setText(QString("%1").arg((int)afi,2,16,QChar('0')).toUpper());
    if(pOut)
        sprintf(pOut,"DSFID=0x%02X AFI=0x%02X BlockSize=%d BlockNum=%d IC_Ref=0x%02X",dsfid,afi,block_size,block_num,ic_ref);
    set_info(QString("Get Status Success"));
    return iret;
}

//get tag block status
void MainWindow::on_btn_access_get_status_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    int idx=m_cmb_access->currentIndex();
    if(idx<0)
        return;
    char pOut[128]={'\0'};
    char* pt=pOut;
    int iret = get_tag_status(m_tags_hf[idx],pt);
    if(iret != NO_ERR)
        return;
    QMessageBox::information(this,"Get Status",QString(pt),QMessageBox::Ok);
}

//open eas
void MainWindow::on_btn_access_open_eas_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_EnDisable_EAS(m_tags_hf.at(idx),true);
    if(iret!=NO_ERR)
        set_info(QString("Open EAS Failed! err=%1").arg(iret),false);
    else
        set_info(QString("Open EAS Success"));
}
//close eas
void MainWindow::on_btn_access_close_eas_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_EnDisable_EAS(m_tags_hf.at(idx),false);
    if(iret!=NO_ERR)
        set_info(QString("Close EAS Failed! err=%1").arg(iret),false);
    else
        set_info(QString("Close EAS Success"));
}
//get eas
void MainWindow::on_btn_access_get_eas_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    BYTE bOpened=0;
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_Check_EAS(m_tags_hf.at(idx),bOpened);
    if(iret!=NO_ERR)
    {
        set_info(QString("Get EAS Failed! err=%1").arg(iret),false);
    }
    set_info(QString("Get EAS Success!"));
    QMessageBox::information(this,"Get EAS",QString("Eas is %1").arg(bOpened==1?"Opened":"Closed"),QMessageBox::Ok);
}
//write afi
void MainWindow::on_btn_access_write_afi_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    BYTE afi=(BYTE)ui->txt_access_afi->text().trimmed().toInt(NULL,16);
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_Write_AFI(m_tags_hf.at(idx),afi);
    if(iret!=NO_ERR)
    {
        set_info(QString("Write AFI Failed! err=%1").arg(iret),false);
    }
    set_info(QString("Write AFI Success!"));
}

//write block
void MainWindow::on_btn_access_write_block_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    DWORD addr,num;
    addr=ui->cmb_access_block_start->currentIndex();
    num=ui->cmb_access_block_count->currentIndex()+1;
    if((addr+num)>ui->cmb_access_block_count->count())
    {
        set_info(QString("Data block number out of range!"),false);
        return;
    }
    QString qstrs=ui->txt_access_block_data->text().trimmed();
    int blen=qstrs.size()/2;
    DWORD wlen=num*4;
    if(blen%4)
    {
        set_info(QString("Block data length(Multiples of 4) error"),false);
        return;
    }
    if(wlen != blen)
    {
        set_info(QString("Block data length error! data length=%1,need length=%2").arg(blen).arg(wlen),false);
        return;
    }
    BYTE byts[blen];//={0};
    memset(byts,0,sizeof(byts));
    bool b=HexStrToBytes(qstrs.toStdString().data(),byts,blen);
    if(!b)
    {
        set_info(QString("Block data format(Hex) error"),false);
        return;
    }
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_WriteData(m_tags_hf.at(idx),addr,num,byts,(DWORD)blen);
    if(iret!=NO_ERR)
    {
        set_info(QString("Write block data Failed! err=%1").arg(iret),false);
        return;
    }
    set_info(QString("Write block data Success!"));

}

//read block
void MainWindow::on_btn_access_read_block_clicked()
{
    if(m_tags_hf.size()<=0)
        return;
    DWORD addr,num;
    addr=ui->cmb_access_block_start->currentIndex();
    num=ui->cmb_access_block_count->currentIndex()+1;
    if((addr+num)>ui->cmb_access_block_count->count())
    {
        set_info(QString("Data block number out of range!"),false);
        return;
    }
    ui->txt_access_block_data->setText(QString("%1").arg(""));
    DWORD blen=num*4;
    BYTE byts[blen];
    memset(byts,0,sizeof(byts));
    int idx=m_cmb_access->currentIndex();
    int iret=m_rdr->func_AccessTag_ReadData(m_tags_hf.at(idx),addr,num,byts,&blen);
    if(iret!=NO_ERR)
    {
        set_info(QString("Read block data Failed! err=%1").arg(iret),false);
        return;
    }
    char strs[blen*2+1];
    memset(strs,'\0',blen*2+1);
    BytesToHexStr(byts,blen,strs);
    ui->txt_access_block_data->setText(QString(strs).toUpper());
    set_info(QString("Read block data Success!"));
}
/*------------------------END-----------------------高频读卡器 HF READER */


/*------------------------BEGIN-----------------------超高频读卡器 UHF READER */
//write memory
void MainWindow::on_btn_access_write_mem_clicked()
{
    cur_tag_index=m_cmb_access->currentIndex();
    if(cur_tag_index<0 || cur_tag_index > m_tags_uhf.size() || m_cmb_access->currentText().trimmed().isEmpty())
        return;

    int m_memBank=ui->cmb_access_mem_bank->currentIndex();
    int mem_start=ui->cmb_access_word_start->currentData().toInt();
    if(m_memBank==1 && mem_start < 2)
    {
        set_info(QString("Word Start of EPC memory must >= 2!"),false);
        ui->cmb_access_word_start->setFocus();
        return;
    }
    else if(mem_start<0)
    {
        set_info(QString("Word Start must >= 0"),false);
        ui->cmb_access_word_start->setFocus();
        return;
    }
    int mem_num=ui->cmb_access_word_count->currentData().toInt();
    if(mem_num<1)
    {
        set_info(QString("Word Count must > 0"),false);
        ui->cmb_access_word_start->setFocus();
        return;
    }
    QString qstrs=ui->txt_access_mem_data->text().trimmed();
    int blen=qstrs.size()/2;
    DWORD wlen=mem_num*2;
    if(blen%2)//left 1 BYTE
    {
        set_info(QString("New data length error (must multiples of 2)"),false);
        ui->txt_access_mem_data->setFocus();
        return;
    }
    if(wlen != blen)
    {
        set_info(QString("New data length error! data length=%1,need length=%2").arg(blen).arg(wlen),false);
        ui->cmb_access_word_count->setFocus();
        return;
    }
    BYTE m_data[blen];//={0};
    memset(m_data,0,sizeof(m_data));
    bool b=HexStrToBytes(qstrs.toStdString().data(),m_data,blen);
    if(!b)
    {
        set_info(QString("New data format(Hex) error"),false);
        return;
    }
    int iret = m_rdr->func_AccessTag_WriteData(m_tags_uhf[cur_tag_index],invenParams->m_accessPwd,m_memBank,mem_start,mem_num,m_data,blen);
    if (iret==0)
    {
        set_info(QString("Write memory Success!"));
    }
    else
    {
        set_info(QString("Write memory Failed! err=%1").arg(iret),false);
    }
}

//read memory
void MainWindow::on_btn_access_read_mem_clicked()
{
    cur_tag_index=m_cmb_access->currentIndex();
    if(cur_tag_index<0 || cur_tag_index > m_tags_uhf.size() || m_cmb_access->currentText().trimmed().isEmpty())
        return;

    int m_memBank=ui->cmb_access_mem_bank->currentIndex();
    int mem_start=ui->cmb_access_word_start->currentData().toInt();
    int mem_num=ui->cmb_access_word_count->currentData().toInt();
    if(mem_start<0)
    {
        set_info(QString("Word Start must >= 0"),false);
        ui->cmb_access_word_start->setFocus();
        return;
    }
    if(mem_num < 1)
    {
        set_info(QString("Word Count must > 0"),false);
        ui->cmb_access_word_start->setFocus();
        return;
    }
    ui->txt_access_mem_data->setText(QString("%1").arg(""));
    DWORD blen=mem_num*2;
    BYTE m_data[blen];//={0};
    int iret = m_rdr->func_AccessTag_ReadData(m_tags_uhf[cur_tag_index], invenParams->m_accessPwd,m_memBank,mem_start,mem_num,m_data,blen);
    if (iret==0)
    {
        set_info(QString("Read memory Success!"));
        char strs[blen*2+1];
        memset(strs,'\0',blen*2+1);
        BytesToHexStr(m_data,blen,strs);
        ui->txt_access_mem_data->setText(QString(strs).toUpper());
    }
    else
    {
        set_info(QString("Read memory Failed! err=%1").arg(iret),false);
    }
}

void MainWindow::on_btn_access_kill_clicked()
{
    cur_tag_index=m_cmb_access->currentIndex();
    if(cur_tag_index<0 || cur_tag_index > m_tags_uhf.size() || m_cmb_access->currentText().trimmed().isEmpty())
        return;

    QString qstr = ui->txt_access_kill_rfu->text().trimmed();
    bool ok=false;
    BYTE rfu=qstr.toUInt(&ok,16);
    if(!ok)
    {
        set_info(QString("RFU err(must 1 BYTE in hex)"),false);
    }

    if(QMessageBox::question(this,"Kill Tag","Are you sure to kill this tag?",QMessageBox::Yes | QMessageBox::No,QMessageBox::No)!=QMessageBox::Yes)
        return;
    int iret = m_rdr->func_AccessTag_UHF_Kill_Tag(m_tags_uhf[cur_tag_index], invenParams->m_accessPwd, invenParams->m_killPwd, rfu);
    if (iret==0)
    {
        set_info(QString("Kill tag Success"));
    }
    else
    {
        set_info(QString("Kill tag Failed! err=%1").arg(iret),false);
    }
}

//显示超高频设置页
void MainWindow::show_uhf_setting(int tab_index)
{
    FrmSetting *frm=new FrmSetting(this);
    frm->setWindowFlags(frm->windowFlags() | Qt::Dialog);
    frm->setWindowModality(Qt::ApplicationModal);
    frm->move(this->pos().rx()+(this->width()-frm->width())/2,this->pos().ry()+(this->height()-frm->height())/2);
    frm->setFixedSize(frm->width(),frm->height());
    frm->sitch_tab(tab_index);
    frm->show();
}

void MainWindow::on_btn_inventory_setting_clicked()
{
    show_uhf_setting(1);
}

void MainWindow::on_btn_uhf_access_setting_clicked()
{
    show_uhf_setting(4);
}

/*----------------------END------------------------- 超高频读卡器 UHF READER */


/*------------------------BEGIN-----------------------安全门控制中心 LSG Control Center */
//init
void MainWindow::create_ir_trigger_view()
{
    ui->tbw_sgl_door_ir_trigger_counter->clear();
    QStringList strList;
    BYTE* szRate;
    int columns=2;

    strList<<tr("IR")<<tr("Occlusion");
    columns=strList.length();
    szRate=new BYTE[columns]{1,2};

    ui->tbw_sgl_door_ir_trigger_counter->setColumnCount(columns);
    ui->tbw_sgl_door_ir_trigger_counter->setHorizontalHeaderLabels(strList);
    int wid=ui->tbw_sgl_door_ir_trigger_counter->size().width()-38;
    int szSum=0;
    for(int i=0;i<columns;i++)
    {
        szSum +=szRate[i];
    }
    for(int i=0;i<columns;i++)
    {
        ui->tbw_sgl_door_ir_trigger_counter->setColumnWidth(i,szRate[i]*wid/szSum);
    }
    delete[] szRate;

    ui->tbw_sgl_door_ir_trigger_counter->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tbw_sgl_door_ir_trigger_counter->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tbw_sgl_door_ir_trigger_counter->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
void MainWindow::init_lsgcc_sgl_door()
{
    ui->lw_sgl_door_output->clear();
    DWORD cnt=6;
    QFont font;
    font.setFamily(QString("Arial"));
    font.setPixelSize(13);
    QString str;
    for (int i = 1; i <= cnt; ++i) {
        str.sprintf("Output #%d",i);
        QListWidgetItem* chk=new QListWidgetItem();
        chk->setFont(font);
        chk->setData(DisplayRole,"text");
        chk->setData(CheckStateRole, Checked);
        chk->setData(UserRole, i-1);//set user data(start from 0)
        chk->setText(str);
        if(i==1)
            chk->setCheckState(CheckState::Checked);
        else
            chk->setCheckState(CheckState::Unchecked);
        ui->lw_sgl_door_output->addItem(chk);
    }

    ui->cmb_sgl_door_gate_id->setCurrentIndex(1);
    ui->cmb_sgl_door_output_mode->setCurrentIndex(2);
    ui->cmb_sgl_door_output_frequency->setCurrentIndex(1);
    create_ir_trigger_view();
}

//显示获取记录页
void MainWindow::show_lsgcc_get_rcd()
{
    FrmRcd_LSGCC *frm=new FrmRcd_LSGCC(this);
    frm->setWindowFlags(frm->windowFlags() | Qt::Dialog);
    frm->setWindowModality(Qt::ApplicationModal);
    frm->move(this->pos().rx()+(this->width()-frm->width())/2,this->pos().ry()+(this->height()-frm->height())/2);
    frm->setFixedSize(frm->width(),frm->height());
    frm->setReader(m_rdr);
    frm->show();
}

void MainWindow::on_lw_sgl_door_output_itemPressed(QListWidgetItem *item)
{
    if(item->checkState()==CheckState::Checked)
        item->setCheckState(CheckState::Unchecked);
    else
        item->setCheckState(CheckState::Checked);
}

void MainWindow::get_selected_outputs(BYTE* outputs,int* output_len)
{
    DWORD _cnt=ui->lw_sgl_door_output->count();
    if(*output_len < _cnt)
    {
        *output_len=0;
        return;
    }
   int len=0;
    for (int i = 0; i < _cnt; ++i) {
        if(ui->lw_sgl_door_output->item(i)->checkState()==CheckState::Checked)
        {
            outputs[len]=ui->lw_sgl_door_output->item(i)->data(UserRole).toInt();//get userrole data
            len++;
        }
        if(len >= (*output_len))
            break;
    }
    *output_len=len;
}
//单门 报警
void MainWindow::on_btn_sgl_door_start_alarm_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    int gate_id = ui->cmb_sgl_door_gate_id->currentIndex();
    int iret = m_rdr->func_LSGCC_SinglelDoor_Alarm(gate_id);
    if(iret != NO_ERR)
    {
        set_info(QString("Make Alarm Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    set_info(QString("Make Alarm Success!"));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}
//单门 操作输出端口 模式
void MainWindow::on_cmb_sgl_door_output_mode_currentIndexChanged(int index)
{
    int mode = index;
    if(mode == 1)//Deactivie
    {
        ui->cmb_sgl_door_output_frequency->clear();
        ui->fra_sgl_door_output_frequency->setVisible(false);
        ui->fra_sgl_door_output_at->setVisible(false);
        ui->fra_sgl_door_output_dt->setVisible(false);
    }
    else {
        ui->cmb_sgl_door_output_frequency->clear();
        ui->cmb_sgl_door_output_frequency->addItem(QString("Always"));
        for(int i=1;i<=255;i++)
            ui->cmb_sgl_door_output_frequency->addItem(QString("%1").arg(i));
        ui->fra_sgl_door_output_frequency->setVisible(true);
        if(mode == 0)//Activie
        {
            ui->fra_sgl_door_output_at->setVisible(false);
            ui->fra_sgl_door_output_dt->setVisible(false);
        }
        else if(mode == 2)//Flash
        {
            ui->fra_sgl_door_output_at->setVisible(true);
            ui->fra_sgl_door_output_dt->setVisible(true);

        }
    }
}
//单门 操作氛围灯
void MainWindow::on_btn_sgl_door_set_atmo_light_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    int gate_id = ui->cmb_sgl_door_gate_id->currentIndex();
    int mode = ui->cmb_sgl_door_output_mode->currentIndex();
    int light_id=ui->cmb_sgl_door_light_color->currentIndex();
    int freq = 0;
    int at = 0;
    int dt =0;
    int iret = 0;
    if(gate_id <= 0)
    {
        set_info(QString("Set AtmosphereLight Gate ID must > 0!"),false);
        goto exit_flag;
    }
    if(mode != 1)//NOT Deactive
    {
        freq = ui->cmb_sgl_door_output_frequency->currentIndex()*(mode==0?1000:1);//active mode use *1000ms
        if(mode == 2)//Flash
        {
            at=ui->txt_sgl_door_output_at->text().trimmed().toInt()*100;
            dt=ui->txt_sgl_door_output_dt->text().trimmed().toInt()*100;
        }
    }
    iret=m_rdr->func_LSGCC_SinglelDoor_SetAtmosphereLight(gate_id,light_id,mode,freq,at,dt);
    if(iret != NO_ERR)
    {
        set_info(QString("Set AtmosphereLight Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    set_info(QString("Set AtmosphereLight Success!"));


exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//单门 操作输出端口
void MainWindow::on_btn_sgl_door_set_output_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    int gate_id = ui->cmb_sgl_door_gate_id->currentIndex();
    int mode = ui->cmb_sgl_door_output_mode->currentIndex();
    BYTE outputs[6] = {0xFF};
    int outputs_len = 6;
    int freq = 0;
    int at = 0;
    int dt =0;
    int iret = 0;
    if(gate_id <= 0)
    {
        set_info(QString("Set Output Gate ID must > 0!"),false);
        goto exit_flag;
    }
    get_selected_outputs(outputs,&outputs_len);
    if(outputs_len<=0)
    {
        set_info(QString("No GPIO/MOS was selected!"),false);
        goto exit_flag;
    }
    if(mode != 1)//NOT Deactive
    {
        freq = ui->cmb_sgl_door_output_frequency->currentIndex();
        if(mode == 2)//Flash
        {
            at=ui->txt_sgl_door_output_at->text().trimmed().toInt()*100;
            dt=ui->txt_sgl_door_output_dt->text().trimmed().toInt()*100;
        }
    }
    iret=m_rdr->func_LSGCC_SinglelDoor_SetOutput(gate_id,outputs,(BYTE)outputs_len,mode,freq,at,dt);
    if(iret != NO_ERR)
    {
        set_info(QString("Set Output Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    set_info(QString("Set Output Success!"));

exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//获取红外触发计数器状态
void MainWindow::on_btn_sgl_door_get_ir_trigger_counter_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    int gate_id = ui->cmb_sgl_door_gate_id->currentIndex();
    DWORD ir_tri_cnt[16];
    BYTE ir_num=16;
    int iret = 0;
    QFont font;
    font.setFamily(QString("Arial"));
    font.setPixelSize(13);
    if(gate_id <= 0)
    {
        set_info(QString("Get IR Trigger Counter Gate ID must > 0!"),false);
        goto exit_flag;
    }

    iret= m_rdr->func_LSGCC_SinglelDoor_GetIRTriggerCount(gate_id, ir_tri_cnt, &ir_num);
    if(iret != NO_ERR)
    {
        set_info(QString("Get IR Trigger Counter Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }

    if(ui->tbw_sgl_door_ir_trigger_counter->rowCount()!= ir_num)
    {
        ui->tbw_sgl_door_ir_trigger_counter->clearContents();
        ui->tbw_sgl_door_ir_trigger_counter->setRowCount(ir_num);
    }

    ui->tbw_sgl_door_ir_trigger_counter->setFont(font);
    for(int i=0;i<ir_num;i++)
    {
        ui->tbw_sgl_door_ir_trigger_counter->setRowHeight(i,15);
        ui->tbw_sgl_door_ir_trigger_counter->setItem(i,0,new QTableWidgetItem(QString("IR #%1").arg(i+1)));
        ui->tbw_sgl_door_ir_trigger_counter->setItem(i,1,new QTableWidgetItem(QString::number(ir_tri_cnt[i])));

        ui->tbw_sgl_door_ir_trigger_counter->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_sgl_door_ir_trigger_counter->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }

    set_info(QString("Get IR Trigger Counter Success!"));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//初始 人流量
void MainWindow::on_btn_lsgcc_people_count_init_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    int type_id=ui->cmb_lsgcc_people_count_type->currentIndex();
    DWORD inPC=ui->txt_lsgcc_people_count_in->text().trimmed().toInt();
    DWORD outPC=ui->txt_lsgcc_people_count_out->text().trimmed().toInt();
    int iret=m_rdr->func_LSGCC_InitPC(type_id,inPC,outPC);
    if(iret != NO_ERR)
    {
        set_info(QString("Init People Count Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    set_info(QString("Init People Count Success!"));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//获取 人流量
void MainWindow::on_btn_lsgcc_people_count_get_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    BYTE option=(BYTE)(ui->cmb_lsgcc_people_count_type->currentIndex() + 1);
    DWORD pcInTotal=0;
    DWORD pcOutTotal=0;
    DWORD pcInDay=0;
    DWORD pcOutDay=0;
    int iret=m_rdr->func_LSGCC_GetPC(option,&pcInTotal,&pcOutTotal,&pcInDay,&pcOutDay);
    if(iret != NO_ERR)
    {
        set_info(QString("Get People Count Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    if(option==1)
    {
        ui->txt_lsgcc_people_count_in->setText(QString("%1").arg(pcInTotal));
        ui->txt_lsgcc_people_count_out->setText(QString("%1").arg(pcOutTotal));
    }
    else {
        ui->txt_lsgcc_people_count_in->setText(QString("%1").arg(pcInDay));
        ui->txt_lsgcc_people_count_out->setText(QString("%1").arg(pcOutDay));
    }
    set_info(QString("Get People Count Success!"));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//获取 系统时间
void MainWindow::on_btn_lsgcc_systime_get_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    DWORD  year;
    BYTE  month;
    BYTE  day;
    BYTE  hour;
    BYTE  minute;
    BYTE  second;
    QString strTime;
    int iret=m_rdr->func_LSGCC_GetSystemTime(&year,&month,&day,&hour,&minute,&second);
    if(iret != NO_ERR)
    {
        set_info(QString("Get System Time Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    strTime.sprintf("%04d-%02d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second);
    set_info(QString("System Time:%1").arg(strTime));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);
}

//设置 系统时间
void MainWindow::on_btn_lsgcc_systime_set_clicked()
{
    setWidgetEnable(ui->fra_access_lsgcc,false);
    DWORD  year = 0;
    BYTE  month =0;
    BYTE  day = 0;
    BYTE  hour=0;
    BYTE  minute=0;
    BYTE  second=0;
    getTimeNow(&year,&month,&day,&hour,&minute,&second);
    int iret=m_rdr->func_LSGCC_SetSystemTime(year,month,day,hour,minute,second);
    if(iret != NO_ERR)
    {
        set_info(QString("Set System Time Failed! err=%1").arg(iret),false);
        goto exit_flag;
    }
    set_info(QString("Set System Time Success!"));
exit_flag:
    setWidgetEnable(ui->fra_access_lsgcc,true);

}

//获取 报警、人流量记录
void MainWindow::on_btn_lsgcc_get_records_clicked()
{
    show_lsgcc_get_rcd();
}

/*----------------------END------------------------- 安全门控制中心 LSG Control Center */


/*------------------------BEGIN-----------------------SCAN MODE (BUFFER MODE) */
void MainWindow::slot_scan_mode_data(int tag_count,vector<CScan_Record> tags,int use_time,int loop_count)
{
    if(tag_count<0)//inventory terminaled
    {
        return;
    }

    m_lock.Enter();
    bool exist = false;
    int sum_count = m_scan_records.size();
    for (int i = 0; i < tag_count; ++i) {
        exist = false;
        for (int j=0; j < sum_count;++j) {
            if(tags.at(i).equal(m_scan_records.at(j)))
            {
                m_scan_records.at(j).m_counter ++;
                exist = true;
                break;
            }
        }
        if(!exist)
        {
            m_scan_records.push_back(tags.at(i));
        }
    }

    sum_count = m_scan_records.size();

    ui->tbw_scan_mode_tags->clearContents();
    ui->tbw_scan_mode_tags->setRowCount(sum_count);

    for(int i=0;i<sum_count;i++)
    {
        ui->tbw_scan_mode_tags->setItem(i,0,new QTableWidgetItem(QString(m_scan_records[i].m_data)));
        ui->tbw_scan_mode_tags->setItem(i,1,new QTableWidgetItem(QString::number(m_scan_records[i].m_counter)));

        ui->tbw_scan_mode_tags->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tbw_scan_mode_tags->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }

    ui->lbl_scan_mode->setText(QString("Tags: %1  \nTime: %2 ms\nLoop: %3").arg(sum_count).arg(use_time).arg(loop_count));

    m_lock.Leave();
}
void MainWindow::slot_scan_mode_end_loop(int iret)
{
    setWidgetEnable(ui->btn_scan_mode_start,true);
    setWidgetEnable(ui->btn_getinfo,true);

    if(iret < 0 && ui->btn_scan_mode_stop->isEnabled())
    {
        setWidgetEnable(ui->btn_scan_mode_stop,false);
        QMessageBox::critical(this,"Scan Mode",QString("Scan Records failed! err=%1").arg(iret),QMessageBox::Ok);
        on_btn_scan_mode_stop_clicked();
    }
}

void MainWindow::on_btn_scan_mode_start_clicked()
{
    setWidgetEnable(ui->btn_scan_mode_start,false);
    setWidgetEnable(ui->btn_getinfo,false);

//    int ant_count=ui->lw_ants->count();
//    BYTE ants[ant_count];
//    memset(ants,0,sizeof(ants));
//    get_selected_antennas(ants,ant_count);
//    if(ant_count<=0)
//    {
//        setWidgetEnable(ui->btn_inventory_start,true);
//        setWidgetEnable(ui->btn_getinfo,true);
//        QMessageBox::warning(this,"Inventory","No Antenna Selected!",QMessageBox::Ok);
//        return;
//    }
    ui->tbw_scan_mode_tags->clearContents();
    ui->tbw_scan_mode_tags->setRowCount(0);
    m_scan_records.clear();
//    int iret=m_rdr->start_scan_mode(RDType.toStdString().c_str(),ants,ant_count);
    int iret=m_rdr->start_scan_mode(RDType.toStdString().c_str());
    if(iret == NO_ERR)//inventory started
    {
        setWidgetEnable(ui->btn_scan_mode_stop,true);
    }
    else
    {
        setWidgetEnable(ui->btn_scan_mode_stop,false);
        setWidgetEnable(ui->btn_scan_mode_start,true);
        setWidgetEnable(ui->btn_getinfo,true);
    }
}

void MainWindow::on_btn_scan_mode_stop_clicked()
{
    setWidgetEnable(ui->btn_scan_mode_stop,false);
    m_rdr->stop_scan_mode();
}
void MainWindow::on_btn_scan_mode_clear_clicked()
{
    m_lock.Enter();
    m_rdr->reset_scan_mode_flag();
    m_scan_records.clear();
    ui->tbw_scan_mode_tags->clearContents();
    ui->tbw_scan_mode_tags->setRowCount(0);
    m_lock.Leave();
}
/*----------------------END------------------------- SCAN MODE (BUFFER MODE) */

